package com.bolt.report.business.modules.report.service;

import com.bolt.convention.data.Record;
import com.bolt.convention.exception.ServiceException;
import com.bolt.report.business.modules.dataset.entity.ReportDataSetEntity;
import com.bolt.report.business.modules.dataset.service.ReportDataSetService;
import com.bolt.report.business.modules.link.dto.converter.ReportLinkConverter;
import com.bolt.report.business.modules.link.entity.ReportLinkEntity;
import com.bolt.report.business.modules.link.service.ReportLinkService;
import com.bolt.report.business.modules.report.dto.ReportDTO;
import com.bolt.report.business.modules.report.dto.converter.ReportConverter;
import com.bolt.report.business.modules.report.entity.ReportEntity;
import com.bolt.report.business.modules.report.repository.ReportRepository;
import com.bolt.report.definition.HyperlinkDefinition;
import com.bolt.report.exception.ReportBizExceptionEnum;
import com.bolt.support.base.service.BaseService;
import com.bolt.support.spring.jpa.jpql.Clauses;
import com.bolt.support.spring.jpa.repository.BasicJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * Auto Generate Javadoc
 *
 * @author 日期:2021-11-22 17:47:51
 *         在线excel设计器
 **/
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
@RequiredArgsConstructor
public class ReportService extends BaseService<ReportEntity, String> {

    private final ReportRepository reportRepository;

    private final ReportDataSetService dataSetService;

    private final ReportLinkService rportLinkService;

    @Override
    protected BasicJpaRepository<ReportEntity, String> getRepository() {
        return reportRepository;
    }

    public ReportDTO load(String id) {
        ReportEntity reportEntity = findOne(id)
                .orElseThrow(() -> new ServiceException(ReportBizExceptionEnum.DATA_NOT_FOUND));
        return ReportConverter.toDTO(reportEntity);
    }

    public List<HyperlinkDefinition> loadHyperlinkConfig(List<String> ids) {
        List<ReportLinkEntity> entities = rportLinkService.findAll(k -> k.lambda().in(ReportLinkEntity::getId, ids).build());
        return  ReportLinkConverter.toDefinition(entities);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReportEntity update(ReportDTO dto) {
        ReportEntity reportEntity = findOne(dto.getId())
                .orElseThrow(() -> new ServiceException(ReportBizExceptionEnum.DATA_NOT_FOUND));
        ReportEntity entity = ReportConverter.toEntity(reportEntity, dto);
        return save(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReportEntity add(ReportDTO dto) {
        ReportEntity entity = ReportConverter.toEntity(dto);
        return save(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReportEntity saveReportDataSet(ReportDTO dto) {
        ReportEntity reportEntity = findOne(dto.getId())
                .orElseThrow(() -> new ServiceException(ReportBizExceptionEnum.DATA_NOT_FOUND));
        Set<ReportDataSetEntity> dataSets = reportEntity.getDataSets();
        ReportDataSetEntity dataSetEntity = dataSetService.saveOrUpdate(dto.getDataSet());
        dataSets.add(dataSetEntity);
        save(reportEntity);
        return reportEntity;
    }

    public List<Record> list() {
        return jpaQueryFactory.select(
                Clauses.of(ReportEntity::getId),
                Clauses.of(ReportEntity::getName))
                .from(Clauses.of(ReportEntity.class))
                .fetch();
    }
}
